package com.lxj.easyadapter;

import ohos.utils.PlainArray;
import org.jetbrains.annotations.NotNull;

/**
 * Created by zhy on 16/6/22.
 */
public final class ItemDelegateManager<T> {

    private PlainArray<ItemDelegate<T>> delegates = new PlainArray<>();

    public final int getItemViewDelegateCount() {
        return this.delegates.size();
    }

    @NotNull
    public final ItemDelegateManager<T> addDelegate(@NotNull ItemDelegate<T> delegate) {
        int viewType = this.delegates.size();
        this.delegates.put(viewType, delegate);
        viewType++;
        return this;
    }

    @NotNull
    public final ItemDelegateManager<T> addDelegate(int viewType, @NotNull ItemDelegate<T> delegate) {
        if (this.delegates.get(viewType) != null) {
            throw new IllegalArgumentException(
                    "An ItemDelegate is already registered for the viewType = "
                            + viewType
                            + ". Already registered ItemDelegate is "
                            + delegates.get(viewType));
        } else {
            this.delegates.put(viewType, delegate);
            return this;
        }
    }

    @NotNull
    public final ItemDelegateManager<T> removeDelegate(@NotNull ItemDelegate<T> delegate) {
        int indexToRemove = this.delegates.indexOfValue(delegate);
        if (indexToRemove >= 0) {
            this.delegates.removeAt(indexToRemove);
        }

        return this;
    }

    @NotNull
    public final ItemDelegateManager<T> removeDelegate(int itemType) {
        int indexToRemove = this.delegates.indexOfKey(itemType);
        if (indexToRemove >= 0) {
            this.delegates.removeAt(indexToRemove);
        }

        return this;
    }

    public final int getItemViewType(T item, int position) {
        int delegatesCount = this.delegates.size();

        for(int i = delegatesCount - 1; i >= 0; --i) {
            ItemDelegate<T> delegate = this.delegates.valueAt(i);
            if (delegate.isThisType(item, position)) {
                return this.delegates.keyAt(i);
            }
        }
        throw new IllegalArgumentException(
                "No ItemDelegate added that matches position=" + position + " in data source");
    }

    public final void convert(@NotNull ViewHolder holder, T item, int position) {
        int delegatesCount = this.delegates.size();

        for(int i = 0; i < delegatesCount; ++i) {
            ItemDelegate<T> delegate = this.delegates.valueAt(i);
            if (delegate.isThisType(item, position)) {
                delegate.bind(holder, item, position);
                return;
            }
        }
        throw new IllegalArgumentException(
                "No ItemDelegateManager added that matches position=" + position + " in data source");
    }

    @NotNull
    public final ItemDelegate<T> getItemViewDelegate(int viewType) {
        return delegates.get(viewType).get();
    }

    public final int getItemLayoutId(int viewType) {
        return this.getItemViewDelegate(viewType).getLayoutId();
    }

    public final int getItemViewType(@NotNull ItemDelegate<T> itemViewDelegate) {
        return this.delegates.indexOfValue(itemViewDelegate);
    }
}
